/****************************************************************************
 * Copyright (C) 2011 Maxim Integrated Products, All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Maxim Integrated Products
 * shall not be used except as stated in the Maxim Integrated Products
 * Branding Policy.
 *
 * The mere transfer of this software does not imply any licenses
 * of trade secrets, proprietary technology, copyrights, patents,
 * trademarks, maskwork rights, or any other form of intellectual
 * property whatsoever. Maxim Integrated Products retains all ownership rights.
 *
 *     Description: Declares Serial Library Function Interfaces
 *             $Id: maxq_serial.h 2680 2011-11-30 17:57:27Z jbrodt $
 *
 ********************************************************************************
 */

/** 
* \file
* \brief  Serial Interface (UART) driver.
* \details  This file defines the driver API including all types and function
*           prototypes.
* \details  All driver function names are prepended by the driver
*           name (serial) and the macro number if multiple SPI macros exist on
*           the microcontroller (e.g. serial1_enable). If the macro number is
*           omitted, the first (0) instance is assumed (e.g. serial_enable =
*           serial0_enabled).
* \details  This driver has configurations in maxq_config.h
* \details  This driver includes internal software FIFO management.
*/

#ifndef __MAXQ_SERIAL_H__
#define __MAXQ_SERIAL_H__

#include "maxq_config.h"

/***** Definitions *****/

/// Serial Modes
typedef enum {
  SERIAL_MODE0 = 0, ///<  serial mode 0 (see user's guide for details)
  SERIAL_MODE1 = 1, ///<  serial mode 1 (see user's guide for details)
  SERIAL_MODE2 = 2, ///<  serial mode 2 (see user's guide for details)
  SERIAL_MODE3 = 3  ///<  serial mode 3 (see user's guide for details)
} SerialMode;

/// Baudrate Settings
typedef int32_t UartBaudRates;
#define BAUD_RATE_INVALID -1    ///<  invalid baudrate setting
#define BAUD_RATE_MODE0L  0     ///<  low speed with serial mode 0 (see user's guide for details)
#define BAUD_RATE_MODE0H  1     ///<  high speed with serial mode 0 (see user's guide for details)
#define BAUD_RATE_MODE2L  2     ///<  low speed with serial mode 2 (see user's guide for details)
#define BAUD_RATE_MODE2H  3     ///<  high speed with serial mode 2 (see user's guide for details)
#define BAUD_RATE_1200    1200  ///<  bps (serial mode 1 or 3)
#define BAUD_RATE_2400    2400  ///<  bps (serial mode 1 or 3)
#define BAUD_RATE_9600    9600  ///<  bps (serial mode 1 or 3)
#define BAUD_RATE_19200   19200 ///<  bps (serial mode 1 or 3)
#define BAUD_RATE_38400   38400 ///<  bps (serial mode 1 or 3)
#define BAUD_RATE_57600   57600 ///<  bps (serial mode 1 or 3)
#define BAUD_RATE_115200  (int32_t)115200 ///<  bps (serial mode 1 or 3)

/// Parity Checking Settings
typedef enum {
  SERIAL_PARITY_NONE = 0, ///< no parity
  SERIAL_PARITY_ODD,      ///< odd parity
  SERIAL_PARITY_EVEN,     ///< even parity
  SERIAL_PARITY_MARK,     ///< mark (1) parity
  SERIAL_PARITY_SPACE     ///< space (0) parity
} SerialParity;

/// Operation Success Status Code
#define SERIAL_NOERROR                             0
/// Baudrate not supported Error Code
#define SERIAL_UNSUPPORTED_BAUD                   -1
/// Specified option is not support by the driver
#define SERIAL_UNSUPPORTED_OPTION                 -2
/// Unknown Serial Library error
#define SERIAL_GENERAL_ERROR                      -3
/// Parity Error
#define SERIAL_PARITY_ERROR                       -4
/// FIFO Buffer Empty Error
#define SERIAL_BUFFER_EMPTY                       -5
/// FIFO Buffer Full Error
#define SERIAL_BUFFER_FULL                        -6


/***** Function Prototypes *****/

/**
 * \brief Returns Serial Library Version number
 */
int serial_version(void);

/**
*   \brief Initializes serial interface with 115200 baudrate
*   \returns #SERIAL_NOERROR if successful, SERIAL_GENERAL_ERROR if an error occurs
*/
int serial_init(void);

/**
*   \brief Configures serial interface baud rate, mode and parity control
*   \param mode    Serial port mode
*   \param baud    Serial port baud rate
*   \param parity  parity control type
*   \returns error status (#SERIAL_NOERROR, #SERIAL_UNSUPPORTED_BAUD,
*            #SERIAL_UNSUPPORTED_OPTION, #SERIAL_GENERAL_ERROR,
*            #SERIAL_PARITY_ERROR, #SERIAL_BUFFER_EMPTY, #SERIAL_BUFFER_FULL)
*/
int serial_setparameters(SerialMode mode, UartBaudRates baud, SerialParity parity);

/**
*   \brief Gets current serial interface configuration details
*   \param mode    Address Location where Serial port mode value will be stored
*   \param baud    Address Location where Serial port baud rate value will be stored
*   \param parity  Address Location where parity control type value will be stored
*/
void serial_getparameters(SerialMode* mode, UartBaudRates* baud, SerialParity* parity);

/**
*   \brief Write data to serial interface
*   \param str     pointer to buffer of data to be written
*   \param Len     number of characters to be written
*   \param dataLen pointer to actual number of characters written
*   \returns error status (#SERIAL_NOERROR, #SERIAL_UNSUPPORTED_BAUD,
*            #SERIAL_UNSUPPORTED_OPTION, #SERIAL_GENERAL_ERROR,
*            #SERIAL_PARITY_ERROR, #SERIAL_BUFFER_EMPTY, #SERIAL_BUFFER_FULL)
*/
int serial_write(uint8_t* str, unsigned int Len, unsigned int* dataLen);

/**
*   \brief Reads data from Serial port
*   \param str     pointer to buffer to store read data
*   \param Len     max number of characters to read
*   \param readLen pointer to actual number of characters read
*   \returns #SERIAL_NOERROR if successful, #SERIAL_BUFFER_EMPTY or 
*            #SERIAL_PARITY_ERROR otherwise
*/
int serial_read(uint8_t* str, unsigned int Len, unsigned int* readLen);

/**
*   \brief Write one data byte to serial port
*   \returns #SERIAL_NOERROR if successful, #SERIAL_BUFFER_FULL otherwise
*/
int serial_putchar(uint8_t outchar);

/**
*   \brief reads one data byte from serial port
*   \returns #SERIAL_NOERROR if successful, #SERIAL_BUFFER_EMPTY or 
*            #SERIAL_PARITY_ERROR otherwise
*/
int serial_getchar(uint8_t* inchar);

/**
*   \brief Stops serial port transmission after the currently transmitting byte
*/
void serial_tx_stop(void);

/**
*   \brief Resumes serial port transmission after a call to serial_tx_stop().
*/
void serial_tx_resume(void);

/**
*   \brief Clears serial library FIFO buffers
*/
void serial_flush(void);

/**
*   \brief     Serial Library Handler
*   \details   This function advances the internal serial library receive and
*              transmit character queues. It can be called from UART interrupt
*              service routine or periodically depending on the application
*              requirements.
*/
void serial_handler(void);


#if (NUM_UART > 0)
/// \sa   serial_init
int serial0_init(void);
/// \sa   serial_setparameters
int serial0_setparameters(SerialMode mode, UartBaudRates baud, SerialParity parity);
/// \sa   serial_getparameters
void serial0_getparameters(SerialMode* mode, UartBaudRates* baud, SerialParity* parity);
/// \sa   serial_write
int serial0_write(uint8_t* str, unsigned int Len, unsigned int* dataLen);
/// \sa   serial_read
int serial0_read(uint8_t* str, unsigned int Len, unsigned int* readLen);
/// \sa   serial_putchar
int serial0_putchar(uint8_t outchar);
/// \sa   serial_getchar
int serial0_getchar(uint8_t* inchar);
/// \sa   serial_tx_stop
void serial0_tx_stop(void);
/// \sa   serial_tx_resume
void serial0_tx_resume(void);
/// \sa   serial_flush
void serial0_flush(void);

// Function aliases
/// \cond 
#define serial_init            serial0_init
#define serial_setparameters   serial0_setparameters
#define serial_getparameters   serial0_getparameters
#define serial_write           serial0_write
#define serial_read            serial0_read
#define serial_putchar         serial0_putchar
#define serial_getchar         serial0_getchar
#define serial_tx_stop          serial0_tx_stop
#define serial_tx_resume       serial0_tx_resume
#define serial_flush           serial0_flush
/// \endcond 
#endif

#if (NUM_UART > 1)
/// \sa   serial_init
int serial1_init(void);
/// \sa   serial_setparameters
int serial1_setparameters(SerialMode mode, UartBaudRates baud, SerialParity parity);
/// \sa   serial_getparameters
void serial1_getparameters(SerialMode* mode, UartBaudRates* baud, SerialParity* parity);
/// \sa   serial_write
int serial1_write(uint8_t* str, unsigned int Len, unsigned int* dataLen);
/// \sa   serial_read
int serial1_read(uint8_t* str, unsigned int Len, unsigned int* readLen);
/// \sa   serial_putchar
int serial1_putchar(uint8_t outchar);
/// \sa   serial_getchar
int serial1_getchar(uint8_t* inchar);
/// \sa   serial_tx_stop
void serial1_tx_stop(void);
/// \sa   serial_tx_resume
void serial1_tx_resume(void);
/// \sa   serial_flush
void serial1_flush(void);
#endif

#endif //__MAXQ_SERIAL_H__
